package com.common.operator;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Morgan Liao
 * 
 */
public class PlainFileOperator {

	/**
	 * It is used for copying one file from source file to dest file.
	 * 
	 * @param sourceFileName
	 * @param destFileName
	 */
	public static void copyFile(String sourceFileName, String destFileName) {

		File destFile = new File(destFileName);
		File origFile = new File(sourceFileName);
		int bytesum = 0;
		int byteread = 0;
		int length = 1024;

		InputStream inputStream;
		FileOutputStream outputStream;

		try {
			if (origFile.exists()) {
				inputStream = new FileInputStream(origFile);
				outputStream = new FileOutputStream(destFile);
				byte[] buffer = new byte[length];
				while ((byteread = inputStream.read(buffer)) != -1) {
					bytesum += byteread;
					outputStream.write(buffer, 0, byteread);
				}
				inputStream.close();
				outputStream.close();
			} else {
				destFile.createNewFile();
			}
		} catch (Exception e) {
			System.out.println("Error in copying file: " + sourceFileName);
			e.printStackTrace();
		}
	}

	public void removeFile(String path) {
		this.removeFile(new File(path));
	}

	public void removeFile(File path) {
		System.out.println("Removing file " + path.getPath());
		if (path.isDirectory()) {
			File[] child = path.listFiles();
			if (child != null && child.length != 0) {
				for (int i = 0; i < child.length; i++) {
					removeFile(child[i]);
					child[i].delete();
				}
			}
		}
		path.delete();
	}

	// Use sPath.matches(matches) to verify path.
	// private static String matches = "[A-Za-z]:\\\\[^:?\"><*]*";
	private File file;
	private boolean flag;

	public boolean deleteFolder(String sPath) {
		flag = false;
		file = new File(sPath);
		if (!file.exists()) {
			return flag;
		} else {
			if (file.isFile()) {
				return deleteFile(sPath);
			} else {
				return deleteDirectory(sPath);
			}
		}
	}

	public boolean deleteFile(String sPath) {
		flag = false;
		file = new File(sPath);

		if (file.isFile() && file.exists()) {
			file.delete();
			flag = true;
		}
		return flag;
	}

	public boolean deleteDirectory(String sPath) {

		if (!sPath.endsWith(File.separator)) {
			sPath = sPath + File.separator;
		}
		File dirFile = new File(sPath);
		if (!dirFile.exists() || !dirFile.isDirectory()) {
			return false;
		}
		flag = true;

		File[] files = dirFile.listFiles();
		for (int i = 0; i < files.length; i++) {
			if (files[i].isFile()) {
				flag = deleteFile(files[i].getAbsolutePath());
				if (!flag) {
					break;
				}

			} else {
				flag = deleteDirectory(files[i].getAbsolutePath());
				if (!flag) {
					break;
				}
			}
		}
		if (!flag) {
			return false;
		}
		
		return dirFile.delete();

	}

    //Read file content and add it to String.
    public static String readFileContentString(String path) throws FileNotFoundException {
    	String line = "";
    	StringBuffer sb = new StringBuffer();
		try {
			BufferedReader br = 
				new BufferedReader(new InputStreamReader(new FileInputStream(path)));
			
			while ((line = br.readLine()) != null) {
				sb.append(line).append("\n");
			}
		} catch (IOException e) {
            System.out.println("It throws out IOException!");
			e.printStackTrace();
		}
		
		return sb.toString();
	}
    
	public static boolean updateFile(String filePath, String fileContent) {
		
		try {	
			File origFile = new File(filePath);
			File tempFile = new File(filePath + ".temp");
			PrintWriter outputStream = new PrintWriter(tempFile);
			outputStream.print(fileContent);
			outputStream.close();
			
			if (origFile.exists()) {
				if (origFile.delete()) {
                   //Empty
				} else {
				    origFile.delete();
				}
                tempFile.renameTo(origFile);
			} else {
				tempFile.renameTo(origFile);
			}
		} catch (FileNotFoundException e) {
            System.out.println("It throws out FileNotFoundException!");
			e.printStackTrace();
			return false;
		}

		return true;
	}

	//Support Chinese.
    public static List<String> readByLine(File file) {
        List<String> content = new ArrayList<String>();
        
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String line = "";
            while ((line = reader.readLine()) != null) {
            	byte[] bytes = line.getBytes();
            	line = new String(bytes, "UTF-8");
            	content.add(line);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    return null;
                }
            }
        }
        return content;
    }
    
    //Support Chinese.
    public static List<String> writeByLine(File file, String s) {
    	
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
	            System.out.println("It throws out IOException!");
				e.printStackTrace();
			}
		}

		OutputStreamWriter write;
		BufferedWriter bufferedWriter = null;
		try {
			write = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
			bufferedWriter = new BufferedWriter(write);

			bufferedWriter.write(s);

			bufferedWriter.close();
		} catch (UnsupportedEncodingException e2) {
            System.out.println("It throws out UnsupportedEncodingException!");
			e2.printStackTrace();
		} catch (IOException e) {
		    System.out.println("It throws out IOException!");
			e.printStackTrace();
		} finally {
            if (bufferedWriter != null) {
                try {
                	bufferedWriter.close();
                } catch (IOException e1) {
                    return null;
                }
            }
        }
		
		return null;
    }
}
